package com.gpt.article.service.impl.taskHandle.task;

import chatgpt.ChatGPT;
import chatgpt.entity.chat.ChatCompletion;
import chatgpt.entity.chat.ChatCompletionResponse;
import chatgpt.entity.chat.Message;
import chatgpt.exception.ChatException;
import com.alibaba.fastjson.JSON;
import com.gpt.article.controller.websocket.WebSocketUsers;
import com.gpt.article.domain.*;
import com.gpt.article.service.*;
import com.gpt.article.service.impl.taskHandle.GenTask;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public  class XiGaoTasker{

    private static Logger logger = LoggerFactory.getLogger(XiGaoTasker.class);
    private static IGptGenArticleContentService iGptGenArticleContentService;
    private static IGptGenArticleService iGptGenArticleService;
    private static IGptGenArticleTaskService iGptGenArticleTaskService;
    private static IGptSpiderArticleService  iGptSpiderArticleService;
    private  static IGptSysFileService gptSysFileService;
    private static ChatCompletion chatCompletion;
    @Autowired
    public void setIGptGenArticleContentService(IGptGenArticleContentService iGptGenArticleContentService) {
        XiGaoTasker.iGptGenArticleContentService = iGptGenArticleContentService;
    }
    @Autowired
    public void setIGptGenArticleService(IGptGenArticleService iGptGenArticleService) {
        XiGaoTasker.iGptGenArticleService = iGptGenArticleService;
    }
    @Autowired
    public void setIGptGenArticleTaskService(IGptGenArticleTaskService iGptGenArticleTaskService) {
        XiGaoTasker.iGptGenArticleTaskService = iGptGenArticleTaskService;
    }
    @Autowired
    public void setIGptSpiderArticleService(IGptSpiderArticleService iGptSpiderArticleService) {
        XiGaoTasker.iGptSpiderArticleService = iGptSpiderArticleService;
    }
    @Autowired
    public void setIGptSysFileService(IGptSysFileService gptSysFileService) {
        XiGaoTasker.gptSysFileService = gptSysFileService;
    }
    public String  getMsgString(String type,Long id,Integer percentage,String status ){
        String jsonString = "";
        Map<String,Object> msgMap = new HashMap<String,Object>();
        if("source".equals(type)){
            msgMap.put("type","source");
        }else{
            msgMap.put("type","task");

        }
        msgMap.put("id",id);
        msgMap.put("percentage",percentage);
        msgMap.put("status",status);
         jsonString = JSON.toJSONString(msgMap);
        return jsonString;
    }

    public boolean restContentLogic(GptSpiderArticle spiderArticle, ChatGPT chatGPT, GenTask xigaoTask, Long taskId)  {
        WebSocketUsers.sendMessageToUsersByText(getMsgString("source",spiderArticle.getId(),0,"2"));
        Integer oneToNum = xigaoTask.getOneToNum();
        Integer txtlength = xigaoTask.getTxtlength();
        Boolean tuswitch = xigaoTask.getTuswitch();
        Boolean xituSwitch = xigaoTask.getXituSwitch();
        String useModel = xigaoTask.getUseModel();


        //提示词处理
        String prompts = spiderArticle.getGenStyle();
        if(StringUtils.isEmpty(prompts)){
            if(StringUtils.isNotEmpty(spiderArticle.getGenStyle())){
                prompts = spiderArticle.getGenStyle();
            }else{
                upTask(taskId,0,1,0,null);
                //更新原文状态
                spiderArticle.setStatus("3");
                spiderArticle.setUpdateTime(DateUtils.getNowDate());
                iGptSpiderArticleService.updateGptSpiderArticle(spiderArticle);
                WebSocketUsers.sendMessageToUsersByText(getMsgString("source",spiderArticle.getId(),0,"3"));
                logger.error(spiderArticle.getTitle()+"-提示词为空！");
                return false;
            }
        }
        //
        prompts.replace("{title}","<"+spiderArticle.getTitle()+">")
        .replace("{keyword}","<"+spiderArticle.getTitle()+">");


        prompts+="\n" +
                "\n最后，我希望结合其他资料改写的文章必须在<"+txtlength+"字左右>" +
                "\n文章的内容是：";

        prompts+=Jsoup.parse(spiderArticle.getArtContent()).text();
//        spiderArticle.getPromptsName()
        Message system = Message.ofSystem(spiderArticle.getTakeRole());
//        Message ast = Message.ofAssistant(StripHT(spiderArticle.getArtContent()));
//        Message ast = Message.ofAssistant(Jsoup.parse(spiderArticle.getArtContent()).text());
        Message user = Message.of(prompts);


            logger.info("正在洗稿：{}",spiderArticle.getTitle());
            long startTime = System.currentTimeMillis();
             chatCompletion = ChatCompletion.builder()
                    .model(useModel)
//                    .model(ChatCompletion.Model.GPT_3_5_TURBO_16K.getName())
                    .messages(Arrays.asList(system,user))
                    .maxTokens(10000)
                    .temperature(0.9)
                    .build();

        logger.info("正在获取文章图：{}",spiderArticle.getTitle());
        if(StringUtils.isEmpty(spiderArticle.getArtContent())){
            logger.error("文章素材内容为空...");
            return false;
        }
            //获取文章所有图
        Document documentContent = Jsoup.parse(spiderArticle.getArtContent());
        Set<String> oranImgList = findImages(documentContent);
        List<String> useImg = new ArrayList<String>();
        //调换图位置
        if(tuswitch){
            useImg = getshuffleImgList(oranImgList);
        }else{
            useImg = new ArrayList<String>(oranImgList);
        }
        //洗图
        if(xituSwitch){
            //如果调换位置+洗图
            //获取文件md5
            List<String> imgMd5List = getMd5XituList(useImg);
            String[] imgMd5s = imgMd5List.toArray(new String[imgMd5List.size()]);
            logger.info("正在准备生图：{}",spiderArticle.getTitle());
            useImg = gptSysFileService.getImgBymd5(imgMd5s);
         }


        Map<String,Object> xtMap = new HashMap<>();
//        //更新原文状态
        spiderArticle.setStatus("2");
        spiderArticle.setUpdateTime(DateUtils.getNowDate());
        iGptSpiderArticleService.updateGptSpiderArticle(spiderArticle);

        for(int i=0;i<oneToNum;i++){
            Message res = null;
            try {
                logger.info("正在准备生成文章：{}",spiderArticle.getTitle());
                ChatCompletionResponse response = chatGPT.chatCompletion(chatCompletion);
                 res = response.getChoices().get(0).getMessage();
            }catch (ChatException e){
                //更新原文状态
                spiderArticle.setStatus("3");
                iGptSpiderArticleService.updateGptSpiderArticle(spiderArticle);
                logger.error("chatgpt执行报错：："+e.getMessage());
                throw e;
            }
            String genContent = res.getContent();


            //处理图
            xtMap = insertOriginImg(Jsoup.parse(genContent),useImg);
            genContent = String.valueOf(xtMap.get("doc"));
//             =  (List<String>)xtMap.get("imgs");


            long endTime = System.currentTimeMillis();
            long elapsedTime = endTime - startTime;
            logger.info("生成成功！耗时：{}",elapsedTime);
            //更新洗稿状态
            int xn = xigaoTask.getXiGaoNum()+1;
            int alln = xigaoTask.getTaskNum();

            int percentage = xn/alln;
            xigaoTask.setXiGaoNum(xn);
            logger.info("当前洗稿进度：{}",percentage);
            //创建洗稿任务数据
            insetGenArticle(genContent,spiderArticle);
            //更新原文状态
            spiderArticle.setStatus("1");
            spiderArticle.setUpdateTime(DateUtils.getNowDate());
            iGptSpiderArticleService.updateGptSpiderArticle(spiderArticle);
            upTask(taskId,xn,0,percentage,"1");
            WebSocketUsers.sendMessageToUsersByText(getMsgString("source",spiderArticle.getId(),0,"1"));
//            WebSocketUsers.sendMessageToUsersByText(String.valueOf(percentage));
        }

//        iGptGenArticleService.updateGptGenArticle(genArticle);
        return true;
    }

    public boolean updateSpiderArt(GptSpiderArticle spiderArticle){
        iGptSpiderArticleService.updateGptSpiderArticle(spiderArticle);
        return true;
    }

    public static String StripHT(String strHtml) {
        String txtcontent = strHtml.replaceAll("</?[^>]+>", ""); //剔出<html>的标签
        txtcontent = txtcontent.replaceAll("<a>\\s*|\t|\r|\n</a>", "");//去除字符串中的空格,回车,换行符,制表符
        return txtcontent;
    }

    /**
     * 获取文中所有图元素
     * @param html
     * @return
     */
    public  Set<String> findImages(Document html) {

        Elements imgs = html.getElementsByTag("img");

        Set<String> images = new HashSet<String>();
        if (imgs!=null && imgs.size() > 0) {
            for (Element element: imgs) {
                String imgSrc = element.attr("src");
                images.add(imgSrc);
            }
        }

        return images;
    }

    /**
     * 根据地址获取图MD5
     * @return
     */
    public List<String> getMd5XituList(List<String> imgList){
//        "/dev-api/profile/upload/2023/11/8/448a0a95e34955db9b140b103b93ab9c.jpg"
        List<String> genImgs = new ArrayList<String>();
        for(String li:imgList){
            String md5 = FileUtils.getNameNotSuffix(li);
            genImgs.add(md5);
        }
        return genImgs;
    }



    /**
     * 生成后插入图
     * @return
     */
    public Map<String,Object>  insertOriginImg(Document genDoc,List<String> imgList){
        Map<String,Object> map = new HashMap<String,Object>();
        String originContent = genDoc.toString();
        String originContentEls[] = originContent.split("</p>");
        StringBuffer  newContent = new StringBuffer();
        int i = 0;
        List<String> useImg = new ArrayList<String>();

        //没有段落标签
        if(originContentEls.length==1){
            //如果有换行符
            String[] lines = originContent.split("\n");
            if(lines.length>1){
                for (String line : lines) {
                    if(i>=imgList.size()||i==originContentEls.length-1){
                        newContent.append(line );
                    }else{
                        newContent.append(line +
                                "<img src=\"" + imgList.get(i) + "\" style=\"display: inline-block;\"   \">");
                        useImg.add(imgList.get(i));
                    }
                    i++;
                }
            }else{
                //如果就是固定的文章没有段落，则随机位置插入一张图
                Random random = new Random();
                int index = random.nextInt(originContent.length()); // 随机生成一个插入位置的下标
//                if(imgList.size()>0){
                if(imgList.size()>0&&i<imgList.size()){
                    String imageTag = "<img src=\"" + imgList.get(i) + "\" style=\"display: inline-block;\"   \">";
                    newContent.append(originContent.substring(0, index) + imageTag + originContent.substring(index)) ; // 在指定位置插入图片标签
                }


            }
        }else{
            for(String li:originContentEls){
                if(i>=imgList.size()||i==originContentEls.length-1){
                    newContent.append(li+"</p>" );
                }else{
                    newContent.append(li+"</p>" +
                            "<img src=\"" + imgList.get(i)+"\" style=\"display: inline-block;\"   \">");
                    useImg.add(imgList.get(i));
                }
//            li+="<img src=\"" + imgList.get(i) + "\">";
                i++;
            }
        }
//        Document newDoc = Jsoup.parse(String.valueOf(newContent));
        map.put("doc",newContent);
        map.put("imgs",useImg);
        return map;
    }

    /**
     * 重置文章中位置
     * @return
     */
    public Document getShuffleUrls(Document originDoc,List<String> imgList){
         String originContent = originDoc.toString();
        String reg = "<img.*?>";
        String originContentEls[] = originContent.split(reg);
        Document newDoc = null;
        return newDoc;
    }




    /**
     * 重置原图图片位置
     * @param imgList
     * @return
     */
    public List<String> getshuffleImgList(Set<String> imgList){
        List<String> list = new ArrayList<>(imgList);
        Collections.shuffle(list);
        return list;
    }


    /**
     * 创建任务数据
     * @param genContent
     * @param spiderArticle
     * @return
     */
    public boolean insetGenArticle(String genContent,GptSpiderArticle spiderArticle){
        //生成新的洗稿的内容
        String reg = "(?<=<title>).*?(?=</title>)";
        String md5pre = DateUtils.dateTimeNow()+spiderArticle.getTitle()+UUID.randomUUID();
        String md5str = Md5Utils.hash(md5pre);
        String newtitle = getNewTitle(reg,genContent);
        String newContent = genContent.replaceAll("<title>"+newtitle+"</title>","");
        GptGenArticleContent gptGenArticleContent =new  GptGenArticleContent();
        gptGenArticleContent.setUrlMd5(md5str);
        gptGenArticleContent.setArtContent(newContent);
        long contenid = iGptGenArticleContentService.insertGptGenArticleContent(gptGenArticleContent);
        GptGenArticle genArticle = new GptGenArticle();
        genArticle.setTitle(newtitle);
        genArticle.setContentId(contenid);
        genArticle.setUrlMd5(md5str);
        genArticle.setStatus("0");
        genArticle.setGenArticleId(spiderArticle.getId());
        genArticle.setGenArticleTitle(spiderArticle.getTitle());
        iGptGenArticleService.insertGptGenArticle(genArticle);
        return true;

    }

    /**
     * 更新进度
     * @param xn
     *   成功
     * @param errNum
     *  失败
     * @param proce
     *   进程
     *
     * @return
     */
    public static boolean upTask(Long taskId,Integer xn, Integer errNum, Integer proce, String status){
        GptGenArticleTask genArticleTask  = new GptGenArticleTask();
        genArticleTask.setId(taskId);
        if(xn!=0){
            genArticleTask.setSuccessNum(xn);
        }

        if(errNum!=0){
            genArticleTask.setErrorNum(errNum);
        }

        if(proce!=0){
            genArticleTask.setProce(proce);
        }
        if(StringUtils.isNotEmpty(status)){
            genArticleTask.setStatus(status);
        }
        if(proce!=0||errNum!=0||xn!=0){
            iGptGenArticleTaskService.updateGptGenArticleTask(genArticleTask);
//                System.out.println("新增的Id"+genArticleTask.getFileId());
//            Long id = iGptGenArticleTaskService.insertGptGenArticleTask(genArticleTask);
//            System.out.println(id+"=======");
        }
        return true;
    }

    public  String getNewTitle(String reg, String content){
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(content);
        String regString = "";
        if( matcher.find() ){
            System.out.println(matcher.group());
            regString = matcher.group();
        }
        return regString;
    }
}
